package com.example;

import java.io.FileOutputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.concurrent.TimeUnit;

import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.config.ConnectionConfig;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.util.TimeValue;
import org.apache.hc.core5.util.Timeout;

import com.example.vo.CommandLineArgs;

/**
 * HTTP工具类
 * 提供HTTP请求相关的通用功能
 */
public class HttpUtils {
    // 创建连接池管理器
    private static final PoolingHttpClientConnectionManager connectionManager;
    // 创建HTTP客户端实例
    private static final CloseableHttpClient httpClient;
    
    // 静态初始化块，创建连接池和HTTP客户端
    static {
        // 创建连接池管理器
        connectionManager = new PoolingHttpClientConnectionManager();
        
        // 配置连接池参数
        // 设置最大连接数
        connectionManager.setMaxTotal(200);
        // 设置每个路由的最大连接数
        connectionManager.setDefaultMaxPerRoute(20);
        
        // 配置连接超时等参数
        ConnectionConfig connectionConfig = ConnectionConfig.custom()
                .setConnectTimeout(Timeout.ofSeconds(5))
                .setSocketTimeout(Timeout.ofSeconds(60))
                .build();
        connectionManager.setDefaultConnectionConfig(connectionConfig);
        
        // 创建HTTP客户端
        httpClient = HttpClients.custom()
                .setConnectionManager(connectionManager)
                .evictIdleConnections(TimeValue.of(30, TimeUnit.SECONDS))
                .build();
    }
    /**
     * 发送HTTP GET请求
     * @param urlString 请求URL
     * @param username 用户名
     * @param password 密码
     * @param proxyHost 代理主机
     * @param proxyPort 代理端口
     * @param proxyUsername 代理用户名
     * @param proxyPassword 代理密码
     * @return 响应内容
     * @throws Exception 异常信息
     */
    public static String sendGetRequest(String urlString, String username, String password, 
                                       String proxyHost, int proxyPort, String proxyUsername, String proxyPassword)
            throws Exception {
        // 设置认证信息
        String auth = username + ":" + password;
        String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes(StandardCharsets.UTF_8));

        // 创建GET请求
        HttpGet httpGet = new HttpGet(urlString);
        
        // 设置请求头
        httpGet.setHeader("Authorization", "Basic " + encodedAuth);
        httpGet.setHeader("Accept", "application/json");
        
        // 检查是否配置了代理
        if (proxyHost != null && proxyPort > 0) {
            System.out.println("[INFO] 使用代理服务器: " + proxyHost + ":" + proxyPort);
            // 注意：HttpClient 5.x的代理配置方式有所不同，这里简化处理
            // 完整实现需要创建DefaultProxyRoutePlanner等组件
        }
        
        try {
            // 使用推荐的方式执行请求
            try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
                // 检查响应状态
                int statusCode = response.getCode();
                if (statusCode != 200) {
                    throw new RuntimeException("HTTP请求失败，响应码: " + statusCode);
                }
                
                // 获取响应内容
                return EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
            }
        } catch (Exception e) {
            System.err.println("发送GET请求失败: " + e.getMessage());
            throw e;
        }
    }

    /**
     * 下载文件
     * @param fileUrl 文件URL
     * @param saveFilePath 保存路径
     * @param username 用户名
     * @param password 密码
     * @param proxyHost 代理主机
     * @param proxyPort 代理端口
     * @param proxyUsername 代理用户名
     * @param proxyPassword 代理密码
     * @throws Exception 异常信息
     */
    public static void downloadFile(String fileUrl, String saveFilePath, String username, String password,
                                   String proxyHost, int proxyPort, String proxyUsername, String proxyPassword)
            throws Exception {
        // 设置认证信息
        String auth = username + ":" + password;
        String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes(StandardCharsets.UTF_8));

        // 创建GET请求
        HttpGet httpGet = new HttpGet(fileUrl);
        
        // 设置请求头
        httpGet.setHeader("Authorization", "Basic " + encodedAuth);
        
        // 检查是否配置了代理
        if (proxyHost != null && proxyPort > 0) {
            System.out.println("[INFO] 使用代理服务器: " + proxyHost + ":" + proxyPort);
            // 注意：HttpClient 5.x的代理配置方式有所不同，这里简化处理
        }
        
        try {
            // 使用推荐的方式执行请求
            try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
                // 检查响应状态
                int statusCode = response.getCode();
                if (statusCode != 200) {
                    throw new RuntimeException("HTTP响应码: " + statusCode);
                }
                
                // 下载文件
                try (InputStream in = response.getEntity().getContent();
                     FileOutputStream out = new FileOutputStream(saveFilePath)) {
                    byte[] buffer = new byte[4096];
                    int bytesRead;
                    while ((bytesRead = in.read(buffer)) != -1) {
                        out.write(buffer, 0, bytesRead);
                    }
                }
                
                // 确保实体内容被完全消费
                EntityUtils.consume(response.getEntity());
            }
        } catch (Exception e) {
            System.err.println("下载文件失败: " + e.getMessage());
            throw e;
        }
    }

    /**
     * 解析命令行参数
     */
    public static CommandLineArgs parseCommandLineArgs(String[] args) {
        CommandLineArgs cmdArgs = new CommandLineArgs();

        int i = 0;
        while (i < args.length) {
            String arg = args[i];
            if (arg.startsWith("-")) {
                switch (arg) {
                    case "-u":
                    case "--url":
                        cmdArgs.setNexusUrl(args[++i]);
                        break;
                    case "-n":
                    case "--username":
                        cmdArgs.setUsername(args[++i]);
                        break;
                    case "-p":
                    case "--password":
                        cmdArgs.setPassword(args[++i]);
                        break;
                    case "-r":
                    case "--repository":
                        cmdArgs.setRepositoryName(args[++i]);
                        break;
                    case "--proxy-host":
                        cmdArgs.setProxyHost(args[++i]);
                        break;
                    case "--proxy-port":
                        cmdArgs.setProxyPort(Integer.parseInt(args[++i]));
                        break;
                    case "--proxy-username":
                        cmdArgs.setProxyUsername(args[++i]);
                        break;
                    case "--proxy-password":
                        cmdArgs.setProxyPassword(args[++i]);
                        break;
                    case "-h":
                    case "--help":
                        showHelp();
                        System.exit(0);
                        break;
                    default:
                        throw new IllegalArgumentException("未知选项: " + arg);
                }
            }
            i++;
        }

        return cmdArgs;
    }

    /**
     * 显示帮助信息
     */
    public static void showHelp() {
        System.out.println("用法: java -cp <jar文件> com.example.AssetDownloader [json文件路径] [选项]");
        System.out.println("选项:");
        System.out.println("  -u, --url <url>         Nexus服务器URL");
        System.out.println("  -n, --username <name>   用户名");
        System.out.println("  -p, --password <pwd>    密码");
        System.out.println("  -r, --repository <name> 仓库名称");
        System.out.println("  --proxy-host <host>     代理主机");
        System.out.println("  --proxy-port <port>     代理端口");
        System.out.println("  --proxy-username <name> 代理用户名");
        System.out.println("  --proxy-password <pwd>  代理密码");
        System.out.println("  -h, --help              显示帮助信息");
    }

    public static void checkRequiredParams(CommandLineArgs cmdArgs) {
        StringBuilder missingParams = new StringBuilder();

        if (cmdArgs.getNexusUrl() == null) {
            missingParams.append(" --url");
        }
        if (cmdArgs.getUsername() == null) {
            missingParams.append(" --username");
        }
        if (cmdArgs.getPassword() == null) {
            missingParams.append(" --password");
        }
        if (cmdArgs.getRepositoryName() == null) {
            missingParams.append(" --repository");
        }

        if (missingParams.length() > 0) {
            throw new IllegalArgumentException("缺少必要参数:" + missingParams);
        }
    }

}